#!/bin/bash
# ANSIBLE_LINUX_ENABLED=true

# NAMESPACE=cloud-infra

# prometheus的svc地址
# PROMETHEUS_URL=http://prometheus-operator-prometheus.cloud-infra:9090

# node-exporter的名称
# NODE_EXPORTER_NAME=prometheus-operator-prometheus-node-exporter

# rabbitmq的名称
# RABBITMQ_NAME=rabbitmq

# es的svc地址
# ELASTICSEARCH_HOST=efk-elasticsearch-coordinating-only.cloud-infra

# es的账号
# EFK_ACCOUNT=elastic

# es的密码
# EFK_PASSWORD=m12345

# redis的svc地址
# REDIS_SVC=wh-redis-redis.cloud-infra
# REDIS_NAME=wh-redis-redis

# minio的svc地址
# MINIO_ENDPOINT=http://192.168.220.91:30664 # 测试用
# MINIO_ENDPOINT=http://minio-minio.cloud-infra

MINIO_NAME=check
# MINIO_ACCESS_KEY=fKDYGlia7F # 测试用
# MINIO_SECRET_KEY=PAls6lksZWy8X3rGWnd4OePwzGW2X9lchxuu1Zob # 测试用
# EXPIRY_DAYS=7

# 定义mariadb主库 Pod 名称
# mariadb_master_pod=192.168.220.91:31059 # 测试用
# MARIADB_MASTER_NAME="cloud-mariadb-master"

# 定义从库 Pod 名称
# MARIADB_SLAVE_NAME="cloud-mariadb-slave"

# 定义从库 Pod 名称
# MARIADB_PASSWORD="f7L2FF5G3t" # 测试用

#
result_dir=/check/

# 获取当前查询时间
CURRENT_TIME=$(date +"%Y-%m-%d")

# readonly CURRENT_TIME

# 输出巡检文件
file_output="wincloud-check-${CURRENT_TIME}.html"
# file_output="check.html"

declare -A os_dict os_suggestion

os_arr=( "kernel_para" "resource_limits" "selinux" "transparent_hugepage" "hugepage" "cpu" "mem_info" "disk" "net" "crontab" "reboot" "syslog" "cpu_info" "os_user_expire" )

os_dict=(
	['kernel_para']="内核参数配置"
	['resource_limits']="资源限制配置"
	['selinux']="selinux配置"
	['transparent_hugepage']="透明大页配置"
	['hugepage']="标准大页配置"
	['cpu']="cpu使用率"
	['mem_info']="内存使用情况"
	['disk']="硬盘使用情况"
	['net']="网络IO" #
	['crontab']="定时任务"
	['reboot']="主机重启时间"
	['syslog']="系统日志异常" #
	['cpu_info']="CPU架构"
	['os_user_expire']="OS用户密码过期检查"
)


os_suggestion=(
['kernel_para']="sysctl -a 显示的/proc/sys相关内核的运行参数如上，主要检查swappiness、kernel_shmall、kernel_shmmax参数。<br>swappiness的建议值为0，表示最大限度使用物理内存。<br>kernel.shmall表示使用的共享内存的总页数大小限制(建议设置内存的80%，单位page，查看page大小 getconf PAGE_SIZE)<br>kernel_shmmax参数单个共享内存段的最大尺寸,建议设置为物理内存的50%"

['resource_limits']="/etc/security/limits.conf文件限制着用户可以使用的最大文件数，最大线程，最大内存等资源使用量<br>"

['selinux']="SELINUX全称为Security Enhanced Linux ，是对系统安全级别更细粒度的设置。<br>
正常normal：Disabled<br>
异常fatal：非Disabled
"

['transparent_hugepage']="透明大页（TransparentHugePages）<br>
透明大页在Linux中有两种主要的使用模式：<br>
1.自动（always）模式：内核自动尝试使用大页分配内存。这是默认模式，但可能在某些情况下导致内存碎片化问题。<br>
 <br>
2.要求（madvise）模式：只有当应用程序明确要求时（通过 madvise() 系统调用），内核才会使用大页分配内存。这种模式适用于更需要控制大页使用的应用场景。<br>
<br>
always：表示系统始终启用透明大页（默认值）。<br>
madvise：表示只有当应用程序通过 madvise() 要求时，才使用透明大页。<br>
never：表示禁用透明大页。
"

['hugepage']="标准大页配置参数：HugePages_Total<br>
正常normal：0<br>
异常fatal：非0
"

['mem_info']="操作系统可用内存需要保证在合理范围内<br>
正常normal：<80%<br>
警告warnning：80%~90%<br>
异常fatal：>90%

"

['cpu']="操作系统CPU使用控制在合理范围内<br>
正常normal：<80%<br>
警告warnning：80%~90%<br>
异常fatal：>90%
"

['disk']='首先关注在生产环境有没有分盘，生产环境建议数据目录和备份目录单独分盘，其次关注磁盘使用率，磁盘使用率过大，将影响系统的稳定性，建议根目录及数据盘使用率不超过80%，如超过85%，需要及时扩容。<br>
正常normal：<75%<br>
警告warnning：75%~80%<br>
异常fatal：>80%
'

['net']="网络IO应较平稳，此项难以判断，仅为完善系统资源指标而收集<br>
网络IO的检查，需要保证稳定性，不稳定的网络可能对数据同步、集群运行有不利的影响"

['crontab']="定时任务"

['reboot']="90天内重启过的主机系统建议检查是否为计划内重启，如否，进一步检查系统日志进行排查"

['syslog']="系统日志错误信息，如果有FATAL、ERROR级别及OOM信息需要重点关注，并进一步排查影响，保证操作系统稳定性"

['cpu_info']="CPU信息，包括了架构、品牌、核数等，常见CPU架构为x86及ARM架构"

['os_user_expire']="若是用户密码已过期或是接近过期，请及时重置密码。<br>
或是调整用户密码永不过期：chage -M 99999 用户名"
)


declare -A node_dict pod_dict rabbitmq_dict es_dict redis_dict mariadb_dict node_suggestion pod_suggestion rabbitmq_suggestion es_suggestion redis_suggestion mariadb_suggestion

node_arr=("node_basic_info" "node_resource_status" "node_disk_status")
pod_arr=("pod_events_exception" "pod_core_exception" "pod_health_exception" "pod_resource_status" "pod_cpu_status" "pod_memory_status" "pod_restart_status")
rabbitmq_arr=("rabbitmq_cluster_status" "rabbitmq_list_queues" "rabbitmq_list_policies" "rabbitmq_plugins" "rabbitmq_logs")
es_arr=("es_health_exception" "es_node_status" "es_index_info" "es_security_info" "es_shard_info" "es_setting_info")
redis_arr=("redis_sync_exception" "redis_auth" "redis_persistence" "redis_memory" "redis_loglevel" "redis_timeout")
mariadb_arr=("mariadb_master_status" "mariadb_slave_status" "mariadb_master_logs" "mariadb_slave_logs" "mariadb_version" "mariadb_messages" "mariadb_connection" "mariadb_slowsql" "mariadb_configmap" "mariadb_general_log" "mariadb_capacity"  "mariadb_fragments" "mariadb_transaction" "mariadb_cache_size" "mariadb_qcache" )


node_dict=(
['node_basic_info']="主机基本信息"
['node_resource_status']="主机资源状况"
['node_disk_status']="硬盘使用情况"
)

pod_dict=(
['pod_events_exception']="事件检查"
['pod_core_exception']="核心组件检查"
['pod_health_exception']="运行异常检查" 
['pod_resource_status']="资源状况检查"
['pod_cpu_status']="cpu利用率检查"
['pod_memory_status']="内存利用率检查"
['pod_restart_status']="自动重启状态检查"
)

rabbitmq_dict=(
['rabbitmq_cluster_status']="集群状态检查" 
['rabbitmq_list_queues']="队列信息检查"
['rabbitmq_list_policies']="消息策略"
['rabbitmq_plugins']="插件查询"
['rabbitmq_logs']="近期日志检查"
)

es_dict=(
['es_health_exception']="健康异常检查"
['es_node_status']="节点列表查询"
['es_index_info']="索引信息检查"
['es_security_info']="集群安全认证"
['es_shard_info']="索引分片查询"
['es_setting_info']="集群设置检查"
)

redis_dict=(
['redis_sync_exception']="同步异常检查"
['redis_auth']="安全认证配置"
['redis_persistence']="持久化检查"
['redis_memory']="内存配置检查"
['redis_loglevel']="服务日志检查"
['redis_timeout']="超时时间配置"
)

mariadb_dict=(
['mariadb_master_status']="主库异常检查" 
['mariadb_slave_status']="从库异常检查"
['mariadb_master_logs']="主库近期日志检查"
['mariadb_slave_logs']="从库近期日志检查"
['mariadb_version']="数据库版本信息检查"
['mariadb_messages']="数据库信息检查"
['mariadb_connection']="数据库连接检查"
['mariadb_slowsql']="慢sql检查"
['mariadb_configmap']="配置文件检查"
['mariadb_general_log']="审计日志参数检查"
['mariadb_capacity']="数据库容量检查"
['mariadb_fragments']="数据库表碎片"
['mariadb_transaction']="数据库长事务"
['mariadb_cache_size']="数据库缓存大小"
['mariadb_qcache']="数据库缓存命中率"
)


node_suggestion=(
['node_basic_info']="主机基本信息，参考此命令查看：kubectl get nodes<br>
当主机显示NotReady时，需要kubectl describe node xx  查看具体事件<br>
<br>
正常normal：Ready<br>
异常fatal：NotReady
"

['node_resource_status']="主机资源状况，包括cpu和内存，参考此命令查看：kubectl top nodes<br>
正常normal：<80%<br>
警告warnning：80%-90%<br>
异常fatal：>90%
"

['node_disk_status']="硬盘使用情况，需要跟grafana结合使用；如磁盘使用率过大，将影响容器运行的稳定性，建议容器挂载的数据盘使用率不超过80%，如超过85%，需要及时扩容。<br>
正常normal：<75%<br>
警告warnning：75%~80%<br>
异常fatal：>80%
"
)

pod_suggestion=(
['pod_events_exception']="事件检查，查看异常或错误信息"

['pod_core_exception']="核心组件检查<br>
在管理节点controlplane上docker容器部署了如下组件：<br>
kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy<br>
<br>
在工作节点worker上docker容器部署了如下组件：<br>
kubelet、kube-proxy<br>
<br>
当组件异常时，应在节点 docker logs 查看具体异常原因，例如：<br>
docker logs kube-apiserver<br>
<br>
查看资源消耗情况，例如：<br>
docker stats kube-apiserver --no-stream
"

['pod_health_exception']="这里只显示有异常状态的pod，需要自行查看异常状态的原因，可参考命令：kubectl describe/kubectl logs 查看具体不正常运行原因"

['pod_resource_status']="pod资源状况，包括cpu和内存参考此命令查看：kubectl top pods"

['pod_cpu_status']="cpu利用率检查，并从高到低排序<br>
正常normal：<80%<br>
警告warnning：80%-90%<br>
异常fatal：>90%
"

['pod_memory_status']="内存利用率检查，并从高到低排序<br>
正常normal：<80%<br>
警告warnning：80%-90%<br>
异常fatal：>90%
"

['pod_restart_status']="自动重启状态检查，24小时内自动重启的全部pod<br>
1、使用grafana查看重启之前的pod的cpu和内存是否超出limits上限，若超出上限，及时扩容pod的cpu和内存；<br>
2、如果没有超出上限，则在管理节点使用k8s命令查看该pod的上一个退出日志：<br>
例如：<br>
kubectl logs -f 目前的pod名称 --previous -n 命名空间<br>
3、如果没有明显日志，则需另外使用其他工具排查问题，具体问题具体分析。
"
)

rabbitmq_suggestion=(
['rabbitmq_cluster_status']="集群状态检查,参考此命令查看：rabbitmqctl cluster_status<br>
Basics：该部分通常提供集群的基本信息，如集群名称、节点数量等。<br>
Disk Nodes：显示集群中作为磁盘节点（disk nodes）的RabbitMQ节点。磁盘节点会在内存和硬盘上同时保存其状态信息，以确保数据的持久性。在RabbitMQ集群中，至少需要一个磁盘节点来安全地存储集群的状态。<br>
Running Nodes：显示当前正在运行的RabbitMQ节点。这些节点是集群中活跃的、能够处理消息传递任务的节点。<br>
Versions：提供有关集群中每个节点上运行的Erlang和RabbitMQ版本的信息。这有助于确保集群中的所有节点都使用兼容的软件版本。<br>
Maintenance Status：显示集群中每个节点的维护状态。如果某个节点正在进行维护操作（如升级、备份等），其维护状态将在此处显示。<br>
Alarms：显示集群中节点的警报信息。如果某个节点出现问题（如内存不足、磁盘空间不足等），它可能会触发警报。这些警报信息对于及时发现和解决集群中的问题至关重要。<br>
Network Partitions（网络分区）：显示集群中是否存在网络分区。网络分区是指集群中的节点由于网络问题而无法相互通信的情况。如果发生网络分区，集群的可靠性和可用性可能会受到影响。<br>
Listeners：提供有关集群中每个节点上运行的监听器的信息。监听器是节点上用于接收客户端连接的端口和协议的组合。通过了解监听器的信息，可以了解集群如何与外部世界进行通信。<br>
Feature Flags（功能标志）：显示集群中启用的特定功能或实验性特性的信息。功能标志允许用户启用或禁用RabbitMQ的某些高级功能或实验性特性。
"

['rabbitmq_list_queues']="队列信息检查,参考此命令查看：rabbitmqctl list_queues | sort --reverse --key 2 --numeric<br>
正常normal：消息堆积小于50000<br>
警告warnning：消息堆积位于50000-100000<br>
异常fatal：消息堆积大于100000<br>
消息堆积还需根据实际情况进行下一步调整判断
"

['rabbitmq_list_policies']="消息策略,参考此命令查看：rabbitmqctl list_policies<br>
vhost：虚拟主机（Virtual Host）的名称。RabbitMQ通过虚拟主机实现多租户，每个虚拟主机都有自己的队列、交换机和绑定等。策略是与虚拟主机相关联的，因此返回的参数中会包含虚拟主机的名称。<br>
name：策略的名称。每个策略都有一个唯一的名称，用于标识该策略。在创建策略时，管理员需要指定策略的名称。<br>
pattern：用于匹配队列和交换机的正则表达式。策略是通过这个正则表达式应用到特定的队列和交换机上的。如果队列或交换机的名称与这个正则表达式匹配，那么该策略就会应用到这个队列或交换机上。<br>
apply-to：策略的应用对象。这个参数指定了策略是应用到队列（queues）上、交换机（exchanges）上，还是同时应用到两者上。<br>
definition：策略的定义。这是一个JSON格式的字符串，包含了策略的具体规则。这些规则定义了如何对匹配到的队列和交换机进行配置，如消息持久化、镜像等。<br>
priority：策略的优先级。当多个策略匹配到同一个队列或交换机时，优先级最高的策略会生效。优先级的数值越小，优先级越高。<br>
<br>
相关命令：<br>
设置策略：<br>
rabbitmqctl set_policy TTL-policy input_notify.input_notify_queue.dlq '{\"messagettl\":60000}' --apply-to queues<br>
<br>
TTL-policy 是⾃定义的策略名称，也可以设置为TTL。<br>
60000 表示消息的TTL为60秒。<br>
<br>
删除策略：<br>
rabbitmqctl clear_policy TTL-policy
"


['rabbitmq_plugins']="启用插件查询,参考此命令查看：rabbitmq_plugins list -e<br>
默认开启的插件如下：<br>
rabbitmq_management<br>
rabbitmq_management_agent<br>
rabbitmq_peer_discovery_common<br>
rabbitmq_peer_discovery_k8s<br>
rabbitmq_shovel<br>
rabbitmq_shovel_management<br>
rabbitmq_web_dispatch<br>
<br>
例如，想开启rabbitmq_prometheus插件（该插件仅支持rabbitmq3.8版本以上）<br>
1、临时配置：<br>
执行命令：rabbitmq-plugins enable rabbitmq_prometheus<br>
<br>
2、永久配置：<br>
在rabbitmq挂载的配置文件下添加enabled_plugins的rabbitmq_prometheus字段<br>
然后重启下rabbitmq服务
"

['rabbitmq_logs']="调用k8s接口查看rabbitmq的日志；近期日志检查，日志是rabbitmq运行正常的重要记录，请详细检查日志是否有报错信息，及时排查<br>
建议的排查过程：<br>
1、打开mq界面，查看是否有较多的消息队列堆积导致报错<br>
2、打开grafana界面，查看mq是否资源不够导致报错
"
)

es_suggestion=(
['es_health_exception']="es集群健康状态，参考此命令查看：curl http://127.0.0.1:9200/_cat/health?v<br>
epoch：时间戳（s）<br>
timestamp：人类可读的时间戳<br>
cluster：集群的名称<br>
status：集群的整体健康状况：<br>
    green：所有主分片和副本分片都正常分配<br>
    yellow: 所有主分片正常分配，但至少有一个副本分片未被分配<br>
    red：某些主分片未被分配<br>
node.total：节点的总数，包括master、data、client三类节点，默认6个<br>
node.data：数据节点数量，即data节点，默认2个<br>
shards：分片（包括主分片和副本分片）的总数<br>
pri：主分片的总数<br>
relo, init, unassign：分别代表重新分配中、初始化中、未分配的分片数<br>
pending_tasks：待处理的任务数，比如索引操作、设置改变等，这里也是0，表明没有积压的任务。<br>
max_task_wait_time：最长等待任务完成的时间（毫秒）<br>
active_shards_percent：活跃分片（即正在工作的分片，包括主分片和已分配的副本分片）占应有总分片数的百分比，如果集群状态不是green，则此值小于100<br>
<br>
三类节点说明：<br>
master - 主节点：<br>
主要功能：维护元数据，管理集群节点状态；不负责数据写入和查询。<br>
配置要点：内存可以相对小一些，但是机器一定要稳定，最好是独占的机器。<br>
<br>
data - 数据节点：<br>
主要功能：负责数据的写入与查询，压力大。<br>
配置要点：大内存，最好是独占的机器。<br>
<br>
client - 客户端节点：<br>
主要功能：负责任务分发和结果汇聚，分担数据节点压力。<br>
配置要点：大内存，最好是独占的机器。
<br>
正常normal：status：green<br>
警告warnning：status：yellow<br>
异常fatal：status：red<br>
<br>
建议排查过程：<br>
1、检查status状态是否为green，如果是yellow暂无需处理，如果是red需要进一步判断和处理，看第2步<br>
<br>
2、检查网络问题<br>
网络问题可能导致节点间通信失败，从而影响分片的分配和同步。<br>
检查集群中各个节点的网络连接情况，确保节点之间可以正常通信。<br>

3、检查磁盘空间<br>
确保Elasticsearch节点的磁盘空间充足。<br>
如果磁盘空间不足，Elasticsearch可能无法为新的分片分配空间。<br>
<br>
4、检查es资源问题<br>
打开grafana界面，查看es的cpu和内存，是否资源充足；若不充足，及时增大es的cpu和内存，相应的JVM参数也要调整。<br>
<br>
5、检查分片分配<br>
使用命令GET _cluster/allocation/explain来获取分片分配失败的原因。<br>
检查是否有分片未分配或分配失败，以及失败的具体原因。<br>
<br>
6、查看索引状态<br>
使用命令curl -XGET 'http://<es-host>:9200/_cat/indices?v'来查看所有索引的状态。<br>
关注health字段，找出哪些索引处于red状态。<br>
<br>
如果某些索引不再需要或已损坏，可以直接删除它们。<br>
使用命令curl -XDELETE 'http://<es-host>:9200/<index-name>' 来删除索引。
"

['es_node_status']="节点列表查询，参考此命令查看：curl http://127.0.0.1:9200/_cat/nodes?v。<br>
ip: 节点ip<br>
heap.percent: 堆内存使用百分比<br>
ram.percent: 运行内存使用百分比<br>
cpu: cpu使用百分比<br>
load_1m: 系统负载的平均值，代表过去1分钟的平均负载<br>
load_5m: 系统负载的平均值，代表过去5分钟的平均负载<br>
load_15m: 系统负载的平均值，代表过去15分钟的平均负载<br>
node.role: 节点承担的角色，具有以下角色：<br>
   d: data node（数据节点）<br>
   m: master eligible node（主节点）<br>
master: 带* 表明该节点是主节点，带-表明该节点是从节点<br>
name: 节点名称
"

['es_index_info']="索引信息检查，参考此命令查看：curl http://127.0.0.1:9200/_cat/indices?v<br>
health: 表示索引的健康状态。可能的值有 green（一切正常）、yellow（所有数据分片都可用，但一些副本尚未分配）、red（一些数据分片不可用）。<br>
status: 索引的打开/关闭状态。通常，索引是 open 状态，表示可以接受数据写入和查询。如果索引被关闭（close），则不会接受新的数据写入，但可以进行查询。<br>
index: 索引的名称。这是你在 Elasticsearch 中为存储数据而创建的特定名称。<br>
uuid: 索引的唯一标识符。每个索引都有一个唯一的 UUID，用于在内部识别和管理索引。<br>
pri: 主分片（primary shards）的数量。主分片是索引中负责存储数据和提供查询能力的基本单元。一个索引创建时，其主分片数量是固定的，之后不能更改。<br>
rep: 副本（replica shards）的数量。副本是分片的副本，用于提供数据的冗余和故障恢复能力。如果主分片所在的节点失效，副本可以升级为主分片，继续提供服务。<br>
docs.count: 索引中的文档总数。这是存储在索引中的文档数量，不包括已被删除的文档。<br>
docs.deleted: 索引中被逻辑删除但未实际从磁盘中移除的文档数量。Elasticsearch 在删除文档时，通常不会立即从磁盘中移除，而是标记为删除，并在后续进行物理删除。<br>
store.size: 索引占用的存储空间大小。这包括所有主分片和副本分片所占用的空间。<br>
pri.store.size: 所有主分片占用的存储空间大小。这是不包括副本分片的情况下，索引占用的空间。<br>
<br>
正常normal：health：green<br>
警告warnning：health：yellow<br>
异常fatal：health：red
"

['es_security_info']="正常normal：有安全认证<br>
警告warnning：没有安全认证<br>
<br>
添加密码：<br>
更换xpack安全校验镜像：bitnami/elasticsearch:7.4.0-debian-xpack<br>
<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-data<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-master<br>
kubectl edit deploy -n cloud-infra efk-elasticsearch-coordinating-only<br>
<br>
进到其中一个efk-elasticsearch-master-0的pod里面<br>
kubectl exec -it -n cloud-infra efk-elasticsearch-master-0  /bin/bash<br>
进到容器目录<br>
cd /opt/bitnami/elasticsearch/<br>
密码初始化<br>
./bin/elasticsearch-setup-passwords interactive<br>
之后等待设置密码，分别设置6个密码：<br>
<br>
elastic<br>
apm_system<br>
kibana_system<br>
logstash_system<br>
beats_system<br>
remote_monitoring_user<br>
<br>
修改密码：<br>
例如将用户elastic修改成密码123456：<br>
curl -H "Content-Type:application/json" -XPOST -u elastic 'http://127.0.0.1:9200/_xpack/security/user/elastic/_password' -d '{ "password" : "123456" }'<br>
<br>
忘记密码：<br>
1、更换镜像<br>
降级没有密码校验的镜像版本：bitnami/elasticsearch:7.4.0-debian<br>
<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-data<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-master<br>
kubectl edit deploy -n cloud-infra efk-elasticsearch-coordinating-only<br>
<br>
2、删除安全索引<br>
在某一个es服务中执行以下命令：<br>
curl -XDELETE http://127.0.0.1:9200/.security-7<br>
<br>
3、重新更新xpack安全镜像<br>
更换原来的xpack安全校验镜像：bitnami/elasticsearch:7.4.0-debian-xpack<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-data<br>
kubectl edit sts -n cloud-infra efk-elasticsearch-master<br>
kubectl edit deploy -n cloud-infra efk-elasticsearch-coordinating-only<br>
<br>
然后按照之前的操作重新设置密码<br>
"

['es_shard_info']="分片查询，参考此命令查看：curl http://127.0.0.1:9200/_cat/shards?v<br>
index: 索引的名称<br>
shard: 分片的编号。ES 7.x默认一个主分片一个副分片<br>
prirep: 表示分片是主分片（p）还是副本分片（r）。<br>
state: 分片的状态。<br>
   STARTED：表示分片已经初始化并可以接受请求<br>
   RELOCATING：正在迁移<br>
   INITIALIZING：正在初始化<br>
   UNASSIGNED：未分配<br>
docs: 该分片中存储的文档数量。<br>
store: 分片数据占用的存储空间大小。<br>
ip: 持有该分片的节点的IP地址<br>
node: 节点的名称<br>
<br>
正常normal：正在初始化（INITIALIZING）、正在迁移（RELOCATING）、已经初始化并可以接受请求（STARTED）<br>
异常fatal：未分配（UNASSIGNED）
"

['es_setting_info']="集群设置，参考此命令查看：curl http://127.0.0.1:9200/_cluster/settings?v"
)

redis_suggestion=(
['redis_sync_exception']="同步异常检查，参考此命令查看：redis-cli role<br>若出现1个master，2个slave，则说明是正常状态<br>若出现其它情况，则需要重启下redis-sentinel和redis，再观察下是否有1个master和2个slave<br>若还是没变化，则需要再排查下其它原因"
['redis_auth']="正常normal：有安全认证<br>
警告warnning：没有安全认证<br>
<br>
认证：CONFIG GET requirepass<br>
为空则说明没有安全认证<br>
<br>
复制认证：CONFIG GET masterauth<br>
为空则说明没有安全认证<br>
<br>
命令重命名：cat /redis/redis.conf |grep -i rename-command<br>
建议将风险较高的命令重命名避免误操作如：FLUSHDB FLUSHALL<br>
<br>
可以在redis.conf配置文件中修改对应的参数<br>
认证：requirepass<br>
复制认证：masterauth<br>
命令重命名：rename-command<br>
<br>
例如：<br>
requirepass Passw0rd@2024<br>
masterauth Passw0rd@2024<br>
rename-command FLUSHALL ""<br>
rename-command FLUSHDB ""<br>
rename-command CONFIG ""<br>
rename-command SHUTDOWN ""<br>
"

['redis_memory']="CONFIG GET loglevel<br>
当前内存使用情况：INFO Memory | grep used_memory_human<br>
当前内存使用上限：CONFIG GET maxmemory<br>
内存淘汰策略：CONFIG GET maxmemory-policy<br>
内存碎片率：INFO Memory | grep mem_fragmentation_ratio<br>
<br>
可以在redis.conf配置文件中修改对应的参数：<br>
当前内存使用上限：maxmemory<br>
内存淘汰策略：maxmemory-policy（noeviction、allkeys-lru、volatile-lru、allkeys-random、volatile-random、volatile-ttl）<br>
noeviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。（默认值）<br>
allkeys-lru: 所有key通用; 优先删除最近最少使用(less recently used ,LRU)的key。<br>
volatile-lru: 只限于设置了expire的部分; 优先删除最近最少使用(less recently used ,LRU)的key。<br>
allkeys-random: 所有key通用; 随机删除一部分key。<br>
volatile-random: 只限于设置了expire的部分; 随机删除一部分key。<br>
volatile-ttl: 只限于设置了expire的部分; 优先删除剩余时间(time to live,TTL) 短的key。<br>
<br>
默认为无删除策略noeviction，写满后禁止新的写入。建议根据键的使用调整为其他删除策略。<br>
<br>
例如：<br>
maxmemory 393216000<br>
maxmemory-policy volatile-lru
"

['redis_persistence']="rdb持久化：CONFIG GET save<br>
当前使用默认持久化设置建议可根据业务需求做出调整，可以在redis.conf配置文件中修改对应的save参数<br>
例如：在 900 秒内最少有 1 个 key 被改动，或者 300 秒内最少有 10 个 key 被改动，以上两个条件随便满足一个，就触发一次保存操作。<br>
则可以在redis.conf配置文件中设置如下值：<br>
save 900 1<br>
save 300 10<br>
<br>
保存之后，CONFIG GET save 命令显示出来的值即为 900 1 300 10<br>
<br>
<br>
aof持久化：CONFIG GET appendonly<br>
可根据持久化需求选择性开启<br>
<br>
可以在redis.conf配置文件中修改对应的参数：<br>
appendonly（no、yes）、appendfsync（always、everyone、no）<br>
<br>
always 表示，每个操作都会执行一次 fsync，是最为安全的方式；<br>
everysec 表示，每秒钟调用一次 fsync ，这样可以保证即使是最坏情况下，也只丢失1秒的数据；<br>
而no表示交给操作系统来处理。<br>
<br>
例如：<br>
开启aof持久化，并且appendfsync设置为everyone，则配置为：<br>
appendonly yes<br>
appendfsync everyone
"

['redis_loglevel']="CONFIG GET loglevel<br>

可以在redis.conf配置文件中修改对应的参数：<br>
日志等级：loglevel（debug、verbose、notice、warning和critical），默认为notice等级<br>
日志路径：logfile<br>
<br>
例如：<br>
loglevel notice<br>
logfile /data/redis.log
"

['redis_timeout']="CONFIG GET timeout<br>
<br>
可以在redis.conf配置文件中修改对应的参数：<br>
超时时间：timeout<br>
<br>
例如：<br>
timeout 500
"
)

mariadb_suggestion=(
['mariadb_master_status']="主库异常检查,参考此命令查看：show master status / show slave status<br>Slave_IO_Running、Slave_SQL_Running，这两个值是Yes表示正常，No是异常<br>Slave_IO线程负责把主库的bin日志(Master_Log)内容，抄写到从库的中继日志上(Relay_Log)。Slave_SQL线程负责把中继日志上的语句在从库上执行一遍。<br>Last_IO_Error，Last_SQL_Error:在出现IO线程错误和SQL线程错误的时候会有值"
['mariadb_slave_status']="从库异常检查,参考此命令查看：show master status / show slave status<br>Slave_IO_Running、Slave_SQL_Running，这两个值是Yes表示正常，No是异常<br>Slave_IO线程负责把主库的bin日志(Master_Log)内容，抄写到从库的中继日志上(Relay_Log)。Slave_SQL线程负责把中继日志上的语句在从库上执行一遍。<br>Last_IO_Error，Last_SQL_Error:在出现IO线程错误和SQL线程错误的时候会有值"
['mariadb_master_logs']="主库近期日志检查，日志是数据库运行正常的重要记录，请详细检查日志是否有报错信息，及时排查"
['mariadb_slave_logs']="从库近期日志检查，日志是数据库运行正常的重要记录，请详细检查日志是否有报错信息，及时排查"

['mariadb_version']="SELECT VERSION();<br>
数据库版本信息检查"

['mariadb_messages']="SELECT table_schema AS 'Database', ENGINE,ROW_FORMAT,TABLE_COLLATION , AUTO_INCREMENT, CREATE_TIME, UPDATE_TIME FROM information_schema.tables GROUP BY table_schema;<br>
数据库信息检查"

['mariadb_connection']="SHOW STATUS LIKE 'Threads_connected';<br>
SHOW PROCESSLIST;<br>
如果数据库的连接数过大，需要检查一下业务和数据库的资源情况，调整相关的连接参数。
"

['mariadb_slowsql']="1、在MySQL中，慢查询日志是一种记录执行时间超过指定阈值的查询的日志。要启用和查看慢查询日志，你可以按照以下步骤操作：<br>
修改MySQL配置文件，添加或更新以下配置项来启用慢查询日志并设置阈值：<br>
[mysqld]<br>
slow_query_log = 1<br>
slow_query_log_file = /bitnami/mariadb/logs/slow_query.log<br>
long_query_time = 2<br>
这里slow_query_log被设置为1来启用慢查询日志，slow_query_log_file指定慢查询日志文件的位置，long_query_time定义了查询的阈值，例如，这里设置为10秒。<br>
2、重启MySQL服务以使配置生效。<br>
3、使用SHOW VARIABLES LIKE 'slow_query_log';查看慢查询日志状态，用SHOW VARIABLES LIKE 'slow_query_log_file';查看慢查询日志文件位置，用SHOW VARIABLES LIKE 'long_query_time';查看或更改阈值。<br>
4、执行一些慢查询，查询会被记录在慢查询日志文件中。<br>
使用mysqldumpslow命令分析慢查询日志文件。例如，查看前10条慢查询：<br>
mysqldumpslow -s at -t 10 /bitnami/mariadb/logs/slow_query.log
"

['mariadb_configmap']="配置文件检查"

['mariadb_general_log']="general_log = OFF # 代表未开启审计日志<br>
general_log = ON # 代表已开启审计日志<br>
开启审计日志比较耗性能和存储，要注意<br>
<br>
以下是开启MySQL审计日志的步骤：<br>
1、在配置文件中添加或修改以下设置：<br>
[mysqld]<br>
# 开启审计日志<br>
general_log = ON<br>
# 指定审计日志文件的路径<br>
general_log_file= /bitnami/mariadb/logs/general.log<br>
2、重启MySQL服务以使配置生效。
"

['mariadb_capacity']="数据库容量检查数据库容量检查，根据容量情况了解业务数据分布情况<br>
total_rows: 数据库总行数<br>
total_data_size_gb: 数据库数据大小<br>
total_index_size_gb: 数据库索引大小<br>
total_size_gb: 数据库数据总大小，total_data_size_gb + total_index_size_gb
"

['mariadb_fragments']="数据库表碎片<br>
storage_engine: 表存储引擎
data_size_gb: 表数据的大小（以 GB 为单位）。<br>
index_size_gb: 表索引的大小（以 GB 为单位）。<br>
free_space_gb: 表碎片的大小（以 GB 为单位）。<br>
total_size_gb: 表数据和索引的总大小（以 GB 为单位）。<br>
fragmentation_percentage: 表碎片率，计算公式为 DATA_FREE / (DATA_LENGTH + INDEX_LENGTH) * 100，表示碎片占比（单位：%）。"

['mariadb_transaction']="SELECT * FROM information_schema.innodb_trx;<br>
数据库长事务"

['mariadb_cache_size']="SHOW VARIABLES LIKE 'query_cache_size';<br>
数据库缓存大小"

['mariadb_qcache']="SHOW STATUS LIKE 'Qcache%';<br>
数据库缓存命中率<br>
<br>
1. Qcache_free_blocks<br>
- 说明：查询缓存中当前空闲的内存块的数量。<br>
- 分析：如果该值较高，表示查询缓存有足够的空间来存储查询结果。否则，可能需要增加 query_cache_size 来提供更多缓存空间。<br>
<br>
2. Qcache_free_memory<br>
- 说明：查询缓存中未使用的空闲内存的字节数。<br>
- 分析：该值可以帮助你了解缓存中是否有足够的空间。低值表示查询缓存空间较小，可能需要增加 query_cache_size。<br>
<br>
3. Qcache_hits<br>
- 说明：查询缓存命中的次数，即从查询缓存中返回的结果数。<br>
- 分析：该值表示缓存的命中率。命中率越高，表示查询缓存的效果越好。如果命中率较低，可以考虑增加查询缓存大小或调整查询模式。<br>
<br>
4. Qcache_inserts<br>
- 说明：查询缓存中插入的新查询结果数。<br>
- 分析：表示有多少查询结果被插入到缓存中。较高的插入次数说明查询缓存频繁被使用，并且查询的结果较为稳定。<br>
<br>
5. Qcache_lowmem_prunes<br>
- 说明：由于查询缓存内存不足，导致缓存中查询结果被清除的次数。<br>
- 分析：这个值越高，表示缓存空间不足，查询缓存无法缓存新的查询结果，通常说明查询缓存大小不足，需要增加 query_cache_size。<br>
<br>
6. Qcache_not_cached<br>
- 说明：没有被缓存的查询数，通常是由于查询包含某些不符合缓存条件的特征。<br>
- 分析：如果该值较高，说明很多查询结果没有被缓存，可能是因为查询使用了无法缓存的特性。可以通过优化查询或改变查询方式来提高缓存命中率。<br>
<br>
7. Qcache_queries_in_cache<br>
- 说明：当前查询缓存中存储的查询结果的数量。<br>
- 分析：这个值显示了当前查询缓存中实际存储了多少个查询结果。通常，较高的值意味着查询缓存被有效利用。<br>
<br>
8. Qcache_total_blocks<br>
- 说明：查询缓存中当前总的内存块数，包括空闲块和已占用的块。<br>
- 分析：这个值可以帮助你了解查询缓存的整体内存使用情况。较大的值表示查询缓存中存储了大量数据。"
)